#include "phatGDI.h"
#include "resource.h"


HWND gWindow;
MSG gMsg;
HINSTANCE gInstance;
PAINTSTRUCT gPS;
HDC	gHDC;

HWND gNewItemDlg;
HWND gNewWeaponDlg;
HWND gNewArmorDlg;

HWND gItemTypeCombo;
HWND gArmorClassCombo;
HWND gArmorTypeCombo;
HWND gArmorProtCombo;
HWND gWeaponDmgCombo;
HWND gWeaponCritCombo;
HWND gWeaponCritModCombo;

pxSStream ss;

extern pxGDI gdi;

pxGDI::pxGDI()
{

}

pxGDI::~pxGDI()
{

}

void pxGDI::init( string sTitle )
{
	WNDCLASSEX winclass;
	// first fill in the window class stucture
	winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	winclass.lpfnWndProc = WindowProc; winclass.hInstance = mInstance;
	winclass.cbClsExtra	= 0; winclass.cbWndExtra = 0; winclass.hIconSm = LoadIcon(mInstance, MAKEINTRESOURCE(EDICONSM));
	winclass.hIcon = LoadIcon(mInstance, MAKEINTRESOURCE(EDICON));
	winclass.hCursor = LoadCursor(mInstance, IDC_CROSS); winclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winclass.lpszMenuName = "EdMenu"; winclass.lpszClassName = MAIN_CLASS;

	// register the window class
	if (!RegisterClassEx(&winclass))
	{  error("Couldn't register "+sTitle);	}

	// create the window
	if (!(mWindow = CreateWindowEx(NULL,MAIN_CLASS,     // class
		sTitle.c_str(),/* title */WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN | WS_VISIBLE,
		0,0,/* initial x,y */SCREEN_WIDTH,SCREEN_HEIGHT,  // initial width, height
		NULL,/* handle to parent */NULL, /* handle to menu */mInstance,/* instance of this application */ NULL)))
	{	error("Couldn't create "+sTitle);	}

	ShowWindow( mWindow, SW_SHOW);
	UpdateWindow( mWindow );
}

void pxGDI::init( string sTitle, int x, int y, int w, int h )
{
	WNDCLASSEX winclass;
	// first fill in the window class stucture
	winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	winclass.lpfnWndProc = WindowProc; winclass.hInstance = mInstance;
	winclass.cbClsExtra	= 0; winclass.cbWndExtra = 0; winclass.hIconSm = LoadIcon(mInstance, MAKEINTRESOURCE(EDICONSM));
	winclass.hIcon = LoadIcon(mInstance, MAKEINTRESOURCE(EDICON));
	winclass.hCursor = LoadCursor(mInstance, IDC_CROSS); winclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	winclass.lpszMenuName	= NULL; winclass.lpszClassName = MAIN_CLASS;

	// register the window class
	if (!RegisterClassEx(&winclass))
	{  error("Couldn't register "+sTitle);	}

	// create the window
	if (!(mWindow = CreateWindowEx(NULL,MAIN_CLASS,     // class
		sTitle.c_str(),/* title */WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		x,y,/* initial x,y */w,h,  // initial width, height
		NULL,/* handle to parent */NULL,/* handle to menu */mInstance,/* instance of this application */NULL)))
	{	error("Couldn't create "+sTitle);	}

	ShowWindow( mWindow, SW_SHOW);
	UpdateWindow( mWindow );
}

void pxGDI::destroy()
{

}

// Not needed yet... more for cross platform stuff
void pxGDI::draw()
{

}

void pxGDI::drawCombo( HWND hid )
{

}

void pxGDI::drawButton( HWND hid )
{

}

void pxGDI::drawCheck( HWND hid )
{

}

void pxGDI::drawRadio( HWND hid )
{

}

void pxGDI::drawOwner( HWND hid )
{

}
// End not needed yet...

inline void pxGDI::addComboItem( HWND hid, int iId, string sItem )
{
	SendMessage( hid,CB_ADDSTRING,NULL,(LPARAM)sItem.c_str() );
	ShowWindow(hid, SW_SHOW);
}

void pxGDI::setComboDef( HWND hid, int iID )
{
	SendMessage(hid,CB_SETCURSEL,(WPARAM)iID,NULL);
}

HWND pxGDI::addCombo( HWND hParent, string sText, int x, int y, int w, int h, int id, DWORD style)
{
	mTmp = NULL;

	mTmp=CreateWindowA( "combobox", sText.c_str(), style|WS_TABSTOP, x,y, w,h, hParent,(HMENU)(id), mInstance,NULL);
	if( mTmp != NULL )
		return mTmp;
	else
	{ error( "Couldn't make a combobox control"); return NULL; }
}

HWND pxGDI::addButton( string sText, int x,int y, int w, int h, int id, DWORD style )
{
	mTmp = NULL;
	mTmp = CreateWindowA( "button",sText.c_str(),style | BS_PUSHBUTTON, x, y, w,h, mWindow, (HMENU)(id), mInstance, NULL);
	if( mTmp != NULL )
		return mTmp;
	else
	{ error("Couldn't make a regular button."); return NULL; }
}

HWND pxGDI::addCheck( string sText,int x,int y, int w, int h, int id, DWORD style )
{
	mTmp = NULL;
	mTmp = CreateWindowA( "button",sText.c_str(), style | BS_CHECKBOX, x,y, w,h, mWindow, (HMENU)(id), gInstance, NULL);
	if( mTmp != NULL )
		return mTmp;
	else
	{ error("Couldn't make a check button"); return NULL; }
}

HWND pxGDI::addRadio( string sText,int x,int y, int w, int h, int id, DWORD style )
{
	mTmp = NULL;
	mTmp = CreateWindowA( "button",sText.c_str(), style | BS_RADIOBUTTON, x,y, w,h, mWindow, (HMENU)(id), gInstance, NULL);
	if( mTmp != NULL )
		return mTmp;
	else
	{ error("Couldn't make radio button.");return NULL; }
}

HWND pxGDI::addOwner( string sText,int x,int y, int w, int h, int id, DWORD style )
{
	mTmp = NULL;
	mTmp = CreateWindowA( "button", sText.c_str(), style|BS_OWNERDRAW, x,y, w,h, mWindow, (HMENU)(id), gInstance, NULL);
	if( mTmp != NULL )
		return mTmp;
	else
	{ error("Couldn't make owner button"); return NULL; }
}

void pxGDI::drawBox( RECT &dst)
{

}

void pxGDI::drawBox( int x1, int y1, int x2, int y2)
{

}

void pxGDI::drawLine( RECT &dst )
{

}

void pxGDI::drawLine( int x1, int y1 )
{

}

void pxGDI::setInstance( HINSTANCE tmp )
{ mInstance = tmp; }


LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch(msg)
	{
	case WM_COMMAND:
		{
			switch(LOWORD(wparam))
			{
			case BUTTON_BS_NEWITEM:
				ShowWindow(gWindow, SW_HIDE);
				gNewItemDlg = CreateDialogParam(gInstance, MAKEINTRESOURCE(IDD_NEWITEM), 0, NewItemProc, 0); ShowWindow(gNewItemDlg, SW_SHOW);
				break;
			case BUTTON_BS_NEWARMOR:
				ShowWindow(gWindow, SW_HIDE);
				gNewArmorDlg = CreateDialogParam(gInstance, MAKEINTRESOURCE(IDD_NEWARMOR), 0, NewArmorProc, 0); ShowWindow(gNewArmorDlg, SW_SHOW);
				break;
			case BUTTON_BS_NEWWEAPON:
				ShowWindow(gWindow, SW_HIDE);
				gNewWeaponDlg = CreateDialogParam(gInstance, MAKEINTRESOURCE(IDD_NEWWEAPON), 0, NewWeaponProc, 0); ShowWindow(gNewWeaponDlg, SW_SHOW);
				 break;
			case BUTTON_BS_EXIT:
			case MENU_FILE_ID_EXIT:
					SendMessage(gWindow, WM_CLOSE, 0, 0);
				break;
			default: break;

			} // end switch wparam

		} break; // end WM_COMMAND

	case WM_DESTROY: 
		shutdown();
		PostQuitMessage(0);
		break;
	default:break;
	} // end switch

	// process any messages that we didn't take care of 
	return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WinProc


//---------------------------------------------------------------------------
INT_PTR CALLBACK NewItemProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{

	int iTmp = 0;
	string sCtmp;
	ofstream foutA;
	const char* file = "item.rpg"; // file to save to...

	char tmp[90];

	foutA.open(file, ios::app );

	LPCTSTR itemTypes[itemTypeCount] = { "Padded", "Leather", "Studded Leather", "Hide" };

	switch(Msg)
	{
	case WM_INITDIALOG:
		{
			gItemTypeCombo = gdi.addCombo( hWndDlg, "", 125, 40, 110, 150, IDC_COMBO_TYPE );

			for( int i = 0; i < itemTypeCount; i++ )
				gdi.addComboItem( gItemTypeCombo, IDC_COMBO_TYPE, itemTypes[i]);

			gdi.setComboDef(gItemTypeCombo, 0);
		}
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDB_DEF_OK:

			if( foutA.is_open())
			{
				GetDlgItemText( hWndDlg, IDC_NAME, tmp, 30);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Name is blank. Impossible");
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_DESC, tmp, 90);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Description is blank. Impossible."); 
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_VALUE, tmp, 5);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Value is blank. Impossible."); 
					break;
				}
				else
				{
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
				}

				GetDlgItemText( hWndDlg, IDC_COMBO_TYPE, tmp, 20);
				sCtmp = tmp;
				for( int i = 0; i < itemTypeCount; i++ )
				{
					if( sCtmp == itemTypes[i] )
						foutA << i << "#" << std::endl;
				}

				foutA.flush();
				foutA.close();
			}
			SendMessage(gNewItemDlg, WM_CLOSE, 0, 0);
			break;
		case IDCANCEL:
			return true;
	}
	break;

	case WM_CLOSE:
		DestroyWindow(gNewItemDlg);
		return true;

	case WM_DESTROY:
		// write values to file if valid, discard if any are invalid
		DestroyWindow(gNewItemDlg);
		ShowWindow(gWindow, SW_SHOW);
		return true;
}
return false;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
INT_PTR CALLBACK NewArmorProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	int iTmp = 0;
	string sCtmp;
	ofstream foutA;
	const char* file = "armor.rpg"; // file to save to...

	char tmp[90];

	foutA.open(file, ios::app );

	LPCTSTR armorTypes[armorTypeCount] = { "Padded", "Leather", "Studded Leather", "Hide", "Scale", "Chain", "Bronze", 
		"Iron", "Half Plate", "Full Plate" };
	LPCTSTR armorClasses[armorClassCount] = { "10", "11", "12", "13", "14", "15", "16", "17", "18", "19" };
	LPCTSTR armorProt[armorProtCount] = { "+0", "+1", "+2", "+3", "+4", "+5", "+6", "+7", "+8", "+9" };
	switch(Msg)
	{
	case WM_INITDIALOG:
		{
			gArmorTypeCombo = gdi.addCombo( hWndDlg, "", 215, 15, 150, 250, IDC_COMBO_A_TYPE );
			gArmorClassCombo = gdi.addCombo( hWndDlg, "", 215, 45, 150, 250, IDC_COMBO_A_CLASS );
			gArmorProtCombo = gdi.addCombo( hWndDlg, "", 215, 75, 150, 250, IDC_COMBO_A_PROT );

			for( int i = 0; i < armorTypeCount; i++ )
				gdi.addComboItem( gArmorTypeCombo, IDC_COMBO_A_TYPE, armorTypes[i] );

			for( int i = 0; i < armorClassCount; i++ )
				gdi.addComboItem( gArmorClassCombo, IDC_COMBO_A_CLASS, armorClasses[i] );

			for( int i = 0; i < armorProtCount; i++ )
				gdi.addComboItem( gArmorProtCombo, IDC_COMBO_A_PROT, armorProt[i] );

			gdi.setComboDef( gArmorClassCombo, 0 );
			gdi.setComboDef( gArmorTypeCombo, 0 );
			gdi.setComboDef( gArmorProtCombo, 0 );
		}
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDOK:
		case IDB_DEF_OK:
			// get and save input here
			if( foutA.is_open())
			{
				GetDlgItemText( hWndDlg, IDC_ANAME, tmp, 30);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Name is blank. Impossible");
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_ADESC, tmp, 90);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Description is blank. Impossible."); 
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_COMBO_A_TYPE, tmp, 20);
				sCtmp = tmp;
				if( sCtmp == armorTypes[0] )
					foutA << 0 << ",";
				else if( sCtmp == armorTypes[1] )
					foutA << 1 << ",";
				else if( sCtmp == armorTypes[2] )
					foutA << 2 << ",";
				else if( sCtmp == armorTypes[3] )
					foutA << 3 << ",";
				else if( sCtmp == armorTypes[4] )
					foutA << 4 << ",";
				else if( sCtmp == armorTypes[5] )
					foutA << 5 << ",";
				else if( sCtmp == armorTypes[6] )
					foutA << 6 << ",";
				else if( sCtmp == armorTypes[7] )
					foutA << 7 << ",";
				else if( sCtmp == armorTypes[8] )
					foutA << 8 << ",";
				else if( sCtmp == armorTypes[9] )
					foutA << 9 << ",";

				GetDlgItemText( hWndDlg, IDC_AVALUE, tmp, 5);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Value is blank. Impossible."); 
					break;
				}
				else
				{
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
				}

				GetDlgItemText( hWndDlg, IDC_COMBO_A_CLASS, (LPSTR)sCtmp.c_str(), 20);
				ss.stringToNumber( sCtmp, iTmp );

				foutA << iTmp << ",";

				GetDlgItemText( hWndDlg, IDC_COMBO_A_PROT, (LPSTR)sCtmp.c_str(), 20);
				// Remove the aesthetic +
				sCtmp[0] = sCtmp[1];
				sCtmp[1] = ' ';
				ss.stringToNumber( sCtmp, iTmp );
				foutA << "-" << iTmp << "#" << std::endl; // add the - b/c of how its imported... have to change when if binary

				foutA.flush();
				foutA.close();
			}
			SendMessage(gNewArmorDlg, WM_CLOSE, 0, 0);
			break;
		case IDCANCEL:
			return true;
		}
		break;

	case WM_CLOSE:

		DestroyWindow(gNewArmorDlg);
		return true;

	case WM_DESTROY:
		// write values to file if valid, discard if any are invalid
		DestroyWindow(gNewArmorDlg);
		ShowWindow(gWindow, SW_SHOW);
		return true;
	}
	return false;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
INT_PTR CALLBACK NewWeaponProc(HWND hWndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{

	int iTmp = 0;
	string sCtmp;
	ofstream foutA;
	const char* file = "weapon.rpg"; // file to save to...

	char tmp[90];

	foutA.open(file, ios::app );

	LPCTSTR weaponCrit[weaponCritCount] = { "18", "19", "20" };
	LPCTSTR weaponCritMod[weaponCtmdCount] = { "x2", "x3", "x4" };
	LPCTSTR weaponDmg[weaponDmgCount] = { 
		"d2", "d3", "d4", "d6", "d8", "d10", "d12", "2d2", "2d3",
		"2d4", "2d6", "2d8", "2d10", "2d12" };

	switch(Msg)
	{
	case WM_INITDIALOG:
		{

			gWeaponCritCombo = gdi.addCombo( hWndDlg, "", 115, 18, 150, 90, IDC_COMBO_W_CRIT );
			gWeaponCritModCombo = gdi.addCombo( hWndDlg, "", 115, 52, 150, 90, IDC_COMBO_W_CTMD );
			gWeaponDmgCombo = gdi.addCombo( hWndDlg, "", 115, 98, 106, 250, IDC_COMBO_W_DMG );

			for( int i = 0; i < weaponCritCount; i++ )
				gdi.addComboItem( gWeaponCritCombo, IDC_COMBO_W_CRIT, weaponCrit[i] );

			for( int i = 0; i < weaponCtmdCount; i++ )
				gdi.addComboItem( gWeaponCritModCombo, IDC_COMBO_W_CTMD, weaponCritMod[i] );

			for( int i = 0; i < weaponDmgCount; i++ )
				gdi.addComboItem( gWeaponDmgCombo, IDC_COMBO_W_DMG, weaponDmg[i] );

			gdi.setComboDef( gWeaponCritCombo, 1 );
			gdi.setComboDef( gWeaponCritModCombo, 0 );
			gdi.setComboDef( gWeaponDmgCombo, 4 );
		}
		break;

	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDB_DEF_OK:
			// Get and save input here

			if( foutA.is_open())
			{
				GetDlgItemText( hWndDlg, IDC_WNAME, tmp, 30);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Name is blank. Impossible");
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_WDESC, tmp, 90);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Description is blank. Impossible."); 
					break;
				}
				else
					foutA << tmp << ",";

				GetDlgItemText( hWndDlg, IDC_WVALUE, tmp, 5);
				sCtmp = tmp;
				if( sCtmp.empty()  )
				{ 
					MB("Value is blank. Impossible."); 
					break;
				}
				else
				{
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
				}

				GetDlgItemText( hWndDlg, IDC_COMBO_W_DMG, tmp, 20);
				sCtmp = tmp; 
				iTmp = ComboBox_GetCurSel(gWeaponDmgCombo);		
				// Remove aesthetics d sCtmp[0]-[6] remove element 0. rest remove element 1 i.e [1]
				if( iTmp < 7 )  // d2-d12
				{
					sCtmp[0] = sCtmp[1];
					sCtmp[1] = ' ';
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
					foutA << 1 << ","; // single die
				}
				else if ( iTmp < 12 ) // 2d2 - 2d8
				{
					sCtmp[0] = sCtmp[2];
					sCtmp[1] = sCtmp[2] = ' ';
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
					foutA << 2 << ","; // two dice
				}
				else // 2d10 && 2d12
				{
					sCtmp[0] = sCtmp[2];
					sCtmp[1] = sCtmp[3];
					sCtmp[2] = sCtmp[3] = ' ';
					ss.stringToNumber( sCtmp, iTmp );
					foutA << iTmp << ",";
					foutA << 2 << ","; // two dice
				}


				GetDlgItemText( gNewWeaponDlg, IDC_COMBO_W_CRIT, tmp, 5);
				sCtmp = tmp;
				ss.stringToNumber( sCtmp, iTmp );
				foutA << iTmp << ",";

				GetDlgItemText( gNewWeaponDlg, IDC_COMBO_W_CTMD, tmp, 5);
				sCtmp = tmp;
				sCtmp[0] = sCtmp[1];
				sCtmp[1] = ' ';
				ss.stringToNumber( sCtmp, iTmp );
				foutA << iTmp << "#" << std::endl;

				foutA.flush();
				foutA.close();

			}
			SendMessage(gNewWeaponDlg, WM_CLOSE, 0, 0);
			break;
		case IDCANCEL:
			return true;
			break;
		}
		break;

	case WM_CLOSE:
		DestroyWindow(gNewWeaponDlg);
		return TRUE;

	case WM_DESTROY:
		// write values to file if valid, discard if any are invalid
		DestroyWindow(gNewWeaponDlg);
		ShowWindow(gWindow, SW_SHOW);
		return true;
	}
	return false;
}
//---------------------------------------------------------------------------
